package action

import (
	"context"
	"net/http"
)

type G钩子请求 struct {
	J节点     *J节点
	Q请求方法   string
	S上下文    context.Context
	G钩子列表   []*G钩子
	X下一个索引  int
	S是否在事务中 bool
	W完成处理程序 finishHandler
}

func (r *G钩子请求) S是否为Post请求() bool {
	return r.Q请求方法 == http.MethodPost
}

func (r *G钩子请求) S是否为Put请求() bool {
	return r.Q请求方法 == http.MethodPut
}

// 判断当前请求是否为Delete请求
func (r *G钩子请求) S是否为Delete请求() bool {
	// 如果请求方法为http.MethodDelete，则返回true，否则返回false
	return r.Q请求方法 == http.MethodDelete
}

func (r *G钩子请求) X下一个() error {

	for {

		var 当前钩子 *G钩子

		for r.X下一个索引+1 < len(r.G钩子列表) && 当前钩子 == nil {

			r.X下一个索引++

			临时钩子 := r.G钩子列表[r.X下一个索引]

			if r.S是否在事务中 {
				if 临时钩子.S事务内处理程序 == nil {
					continue
				}
				当前钩子 = 临时钩子
			} else {
				if 临时钩子.C处理程序 == nil {
					continue
				}
				当前钩子 = 临时钩子
			}

		}

		if 当前钩子 != nil {
			if r.X下一个索引 < len(r.G钩子列表) {
				if r.S是否在事务中 {
					return 当前钩子.S事务内处理程序(r.S上下文, r)
				}

				return 当前钩子.C处理程序(r.S上下文, r)
			}
		}

		return r.W完成处理程序(r.S上下文, r.J节点, r.Q请求方法)
	}

}

type G钩子 struct {
	S适用场景 []string
	// 事务外，可执行参数校验，IO等耗时操作
	C处理程序 func(ctx context.Context, req *G钩子请求) error
	// 事务内，尽量少执行耗时操作 (无论request配置中是否开启事务，都会先执行handler然后在范围内执行HandlerInTransaction)
	S事务内处理程序 func(ctx context.Context, req *G钩子请求) error
}

type finishHandler func(ctx context.Context, n *J节点, method string) error

func G根据访问名获取钩子列表(钩子映射 map[string][]*G钩子, 访问名称 string) []*G钩子 {
	钩子列表 := append(钩子映射["*"], 钩子映射[访问名称]...)
	return 钩子列表
}
